home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / utility / fsco3712.zip / DECODE_C.C < prev    next >
C/C++ Source or Header  |  1993-12-25  |  2KB  |  103 lines

  1. /***** Decode.c (25.12.93) by Flavio Stanchina *****/
  2.  
  3. #include <exec/types.h>
  4. #include <dos/dos.h>
  5. #include <dos/stdio.h>
  6.  
  7. #include <clib/exec_protos.h>
  8. #include <clib/dos_protos.h>
  9.  
  10. #if defined(__SASC)
  11. #define _USEOLDEXEC_
  12. #include <proto/exec.h>
  13. #include <proto/dos.h>
  14. #endif
  15.  
  16. #include "FSCode.h"
  17.  
  18. /* Skip spaces, newlines, tabs and whatever other control character slipped in */
  19. static __inline LONG MyGetC(BPTR fh)
  20. {
  21.     register LONG c;
  22.     do { c = FGetC(fh); } while((c >= 0) && (c <= 32));
  23.     return c;
  24. }
  25.  
  26. LONG Decode(BPTR in, BPTR out, LONG *size_ptr, ULONG *crc_ptr)
  27. {
  28.     LONG size = 0, skip = 0;
  29.     ULONG crc = 0xFFFFFFFF; /* preload shift register, per CRC-32 spec */
  30.     ULONG tmp;
  31.     char buf[4];
  32.     LONG c;
  33.  
  34. get_next:
  35.     tmp = 0;
  36.  
  37.     /* 1 */
  38.     c = MyGetC(in);
  39.  
  40.     if(c == ENDSTREAMCH) return c;
  41.     if(c == '!')
  42.     {
  43.         UnGetC(in, c);
  44.         *size_ptr = size;
  45.         *crc_ptr = crc;
  46.         return 0;
  47.     }
  48.     if(c == '#') skip = 1;
  49.     else { tmp += c - 42; tmp *= 85; }
  50.  
  51.     /* 2 */
  52.     c = MyGetC(in);
  53.  
  54.     if(c == ENDSTREAMCH) return c;
  55.     if(c == '!') return c;
  56.     if(c == '#') skip = 2;
  57.     else { tmp += c - 42; tmp *= 85; }
  58.  
  59.     /* 3 */
  60.     c = MyGetC(in);
  61.  
  62.     if(c == ENDSTREAMCH) return c;
  63.     if(c == '!') return c;
  64.     if(c == '#') skip = 3;
  65.     else { tmp += c - 42; tmp *= 85; }
  66.  
  67.     /* 4 */
  68.     c = MyGetC(in);
  69.  
  70.     if(c == ENDSTREAMCH) return c;
  71.     if(c == '!') return c;
  72.  
  73.     tmp += c - 42; tmp *= 85;
  74.  
  75.     /* 5 */
  76.     c = MyGetC(in);
  77.  
  78.     if(c == ENDSTREAMCH) return c;
  79.     if(c == '!') return c;
  80.  
  81.     tmp += c - 42;
  82.  
  83.     /* Conversion to char truncates, so no & 0xFF needed */
  84.     buf[0] = tmp;
  85.     tmp >>= 8;
  86.     buf[1] = tmp;
  87.     tmp >>= 8;
  88.     buf[2] = tmp;
  89.     tmp >>= 8;
  90.     buf[3] = tmp;
  91.  
  92.     /* Write out the correct amount of data and calculate CRC */
  93.     switch(skip)
  94.     {
  95.         case 0: FPutC(out, buf[3]); size++; crc = crc32_stream(buf[3], crc);
  96.         case 1: FPutC(out, buf[2]); size++; crc = crc32_stream(buf[2], crc);
  97.         case 2: FPutC(out, buf[1]); size++; crc = crc32_stream(buf[1], crc);
  98.         case 3: FPutC(out, buf[0]); size++; crc = crc32_stream(buf[0], crc);
  99.     }
  100.  
  101.     goto get_next;
  102. }
  103.